package com.abcode.rabbitmq.config;

import com.abcode.rabbitmq.callback.ConfirmMessageCallback;
import com.abcode.rabbitmq.callback.ConfirmMessageReturnCallback;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.core.*;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import java.util.HashMap;
import java.util.Map;

/**
 *
 */
@Slf4j
@Configuration
public class RabbitConfig {
    public static final String EXCHANGE_DIRECT_TEST = "TestDirectExchange";
    public static final String QUEUE_DIRECT_TEST = "TestDirectQueue";
    public static final String ROUTING_DIRECT_TEST = "TestDirectRouting";

    public static final String EXCHANGE_FANOUT_TEST = "TestFanoutExchange";

    public static final String QUEUE_FANOUT_COMMON = "TestFanoutCommon";
    public static final String QUEUE_FANOUT_TEST_1 = "TestFanoutQueue1";
    public static final String QUEUE_FANOUT_TEST_2 = "TestFanoutQueue2";
    public static final String QUEUE_FANOUT_TEST_3 = "TestFanoutQueue3";
    public static final String QUEUE_FANOUT_TEST_4 = "TestFanoutQueue4";


    @Autowired
    ConfirmMessageCallback confirmMessageCallback;
    @Autowired
    ConfirmMessageReturnCallback returnCallback;

    @Autowired
    public void setConfirmCallback(RabbitTemplate rabbitTemplate){
        rabbitTemplate.setConfirmCallback(confirmMessageCallback);
        rabbitTemplate.setReturnsCallback(returnCallback);
    }

    //<editor-fold desc="直接消息">

    @Bean
    public Queue TestDirectQueue() {
        // durable:是否持久化,默认是false,持久化队列：会被存储在磁盘上，当消息代理重启时仍然存在，暂存队列：当前连接有效
        // exclusive:默认也是false，只能被当前创建的连接使用，而且当连接关闭后队列即被删除。此参考优先级高于durable
        // autoDelete:是否自动删除，当没有生产者或者消费者使用此队列，该队列会自动删除。
        //   return new Queue("TestDirectQueue",true,true,false);
        //一般设置一下队列的持久化就好,其余两个就是默认false
        //return new Queue(QUEUE_DIRECT_TEST, true);
        // 单活模式 队列
        return creatQueue(QUEUE_DIRECT_TEST);
    }
    @Bean
    DirectExchange TestDirectExchange() {
        return new DirectExchange(EXCHANGE_DIRECT_TEST, true, false);
    }
    @Bean
    Binding bindingDirect() {
        return BindingBuilder.bind(TestDirectQueue()).to(TestDirectExchange()).with(ROUTING_DIRECT_TEST);
    }

    /**
     * 创建⼀个 单活模式的队列
     *
     * @param name
     * @return queue
     */
    private Queue creatQueue(String name) {
        HashMap<String, Object> args = new HashMap<>();
        // x-single-active-consumer 单活模式 队列
        // 表⽰是否最多只允许⼀个消费者消费，如果有多个消费者同时绑定，则只会激活第⼀个，
        // 除⾮第⼀个消费者被取消或者死亡，才会⾃动转到下⼀个消费者。
        args.put("x-single-active-consumer", true);
        return new Queue(name, true, false, false, args);
    }

    //</editor-fold>


    //<editor-fold desc="广播消息">

    /** 交换机 */
    //@Bean
    public FanoutExchange fanoutExchange() {
        return new FanoutExchange(EXCHANGE_FANOUT_TEST);
    }

    //@Bean
    public Queue testFanoutQueue1() {
        Map<String, Object> args = new HashMap<>();
        // 设置队列超时时间为60秒，需要注意的是，“x-expires”参数的时间是从队列最后一次被使用的时间开始计算的，
        // 也就是说，如果队列一直处于被使用的状态，则队列不会被自动删除。
        args.put("x-expires", 60000);
        Queue queue= new Queue(QUEUE_FANOUT_TEST_1, false, false, true, args);
        return queue;
    }

    //@Bean
    public Queue testFanoutQueue2() {
        return new Queue(QUEUE_FANOUT_TEST_2, true);
    }

    //@Bean
    public Queue testFanoutQueue3(){
        //设置ttl,单位ms
        return QueueBuilder.durable(QUEUE_FANOUT_TEST_3).ttl(10000).build();
    }

    //@Bean
    public Queue myQueue() {
        return new Queue(QUEUE_FANOUT_COMMON);
    }

    //@Bean
    public Binding bindingCommon() {
        return BindingBuilder.bind(myQueue()).to(fanoutExchange());
    }

    /** 通过@Qualifier注解指定要绑定的队列1到交换机 */
    //@Bean
    public Binding bindingQueue1(Queue testFanoutQueue1, FanoutExchange fanoutExchange) {
        Binding binding = BindingBuilder.bind(testFanoutQueue1).to(fanoutExchange);
        log.info("消息队列：[{}] 成功绑定到交换机：[{}] ................",testFanoutQueue1.getName(),fanoutExchange.getName());
        return binding;
    }
    //@Bean
    public Binding bindingQueue2(Queue testFanoutQueue2, FanoutExchange fanoutExchange) {
        Binding binding = BindingBuilder.bind(testFanoutQueue2).to(fanoutExchange);
        log.info("消息队列：[{}] 成功绑定到交换机：[{}] ................",testFanoutQueue2.getName(),fanoutExchange.getName());
        return binding;
    }
    //@Bean
    public Binding bindingQueue3(Queue testFanoutQueue3, FanoutExchange fanoutExchange) {
        Binding binding = BindingBuilder.bind(testFanoutQueue3).to(fanoutExchange);
        log.info("消息队列：[{}] 成功绑定到交换机：[{}] ................",testFanoutQueue3.getName(),fanoutExchange.getName());
        return binding;
    }
    //</editor-fold>
}